﻿/*******************************************************************************
#                    QuestionBroker.cs
#  Comment:
#
#  Current Version: V1.0
#  Author: 
#
#  History List:
#  V1.0    Created by Onions@2009-8-18 13:39:32
#
#******************************************************************************/
#region Usings
using System;
using System.Collections.Generic;
using System.Text;
using System.Data;
using SYS.Basic;

using ExpertMIS.Brokers;
using ExpertMIS.Entities;
using System.Collections;
using SYS.Common.Broker;
using IBatisNet.Common.Utilities;
#endregion

namespace ExpertMIS.Brokers
{
    public class QuestionBroker : ExpertMISBaseBroker
    {
        #region Private Fields
        private List<string> _searchFields = new List<string>();
        #endregion

        #region Private Methods

        private object UpdateQuestionEntity(IEntity entity)
        {
            return SqlMap.Update("UpdateQuestionEntity", entity);
        }

        private object InsertQuestionEntity(IEntity entity)
        {
            return SqlMap.Insert("InsertQuestionEntity", entity);
        }

        private object DeleteQuestionEntity(IEntity entity)
        {
            return SqlMap.Delete("DeleteQuestionEntity", entity);
        }

        private void InitSearchFields()
        {
            if (_searchFields.Count <= 0)
            {
                _searchFields.Add("F_Title");
                _searchFields.Add("F_Context");
            }
        }

        private string MakeSearchWhere(string keywords)
        {
            StringBuilder sbWhere = new StringBuilder();
            if (string.IsNullOrEmpty(keywords)) return "";

            string[] keys = keywords.Split(' ');

            InitSearchFields();

            foreach (string key in keys)
            {
                if (string.IsNullOrEmpty(key.Trim())) continue;

                if (sbWhere.Length > 0) sbWhere.Append(" OR ");
                //sbWhere.Append(string.Format(" contains (*,'\"{0}\"')", key.Replace("'","''")));
                foreach (string field in _searchFields)
                {
                    if (sbWhere.Length > 0) sbWhere.Append(" OR ");
                    sbWhere.Append(string.Format(" {0} like '%{1}%' ", field, key));
                }
            }

            return sbWhere.ToString();
        }

        #endregion

        #region Override Methods

        protected override IEntity ProcessGetEntity(System.Collections.Hashtable keys)
        {
            if (!keys.Contains("OID")) throw new Exception("invalid request parameters.");
            return SqlMap.QueryForObject<IEntity>("SelectQuestionEntityByOID", keys["OID"] as string);
        }

        protected override bool ProcessSaveEntity(IEntity entity, Hashtable request)
        {
            QuestionEntity question = entity as QuestionEntity;

            try
            {
                SqlMap.BeginTransaction();
                if (entity.EntityState == EntityState.New)
                {
                    InsertQuestionEntity(entity);
                    entity.EntityState = EntityState.Old;
                }
                else
                {
                    UpdateQuestionEntity(entity);
                }

                // wdong, 2009-09-06, add request != null
                if (request != null && request["domains"] != null)
                {
                    List<string> domainList = request["domains"] as List<string>;
                    List<QuestionDomainEntity> domainEntityList = new List<QuestionDomainEntity>();

                    QuestionDomainBroker domainBroker = new QuestionDomainBroker();
                    foreach (string domain in domainList)
                    {
                        QuestionDomainEntity domainEntity = domainBroker.NewEntity() as QuestionDomainEntity;
                        domainEntity.QuestionOID = question.OID;
                        domainEntity.DomainOID = domain;
                        domainEntityList.Add(domainEntity);
                    }

                    domainBroker.UpdateQuestionDomains(question.OID, domainEntityList);
                }

                if (request != null && request["experts"] != null)
                {
                    List<string> expertList = request["experts"] as List<string>;
                    List<QuestToExpertsEntity> questToExpertEntityList = new List<QuestToExpertsEntity>();

                    QuestToExpertsBroker questToExpertBroker = new QuestToExpertsBroker();
                    foreach (string expert in expertList)
                    {
                        QuestToExpertsEntity questToExpert = questToExpertBroker.NewEntity() as QuestToExpertsEntity;
                        questToExpert.QuestionOID = question.OID;
                        questToExpert.ExpertOID = expert;
                        questToExpertEntityList.Add(questToExpert);
                    }

                    questToExpertBroker.UpdateQuestionToExperts(question.OID, questToExpertEntityList);
                }

                SqlMap.CommitTransaction();

                return true;
            }
            catch
            {
                SqlMap.RollBackTransaction();

                return false;
            }
        }

        protected override IEntity ProcessNewEntity()
        {
            QuestionEntity entity = new QuestionEntity();

            // initial entity object

            return entity;
        }

        protected override bool ProcessRemoveEntity(IEntity entity, Hashtable request)
        {
            try
            {
                DeleteQuestionEntity(entity);
                return true;
            }
            catch
            {
                return false;
            }
        }

        #endregion

        #region Public Method
        public DataTable SearchQuestionsByKeywords(string keywords, PagingSize pagingSize)
        {
            if (string.IsNullOrEmpty(pagingSize.SearchKey)) pagingSize.SearchKey = "1=1";

            string sql = "SELECT * FROM T_QUE_Question";
            string where = MakeSearchWhere(keywords);

            if (!string.IsNullOrEmpty(where))
            {
                pagingSize.SearchKey = string.Format("({0}) AND F_Status <> 0 AND ({1})", pagingSize.SearchKey, where);
            }
            else
            {
                pagingSize.SearchKey = string.Format("({0}) AND F_Status <> 0", pagingSize.SearchKey);
            }
            pagingSize.SortExpression = " F_UPDATEDATE DESC ";

            SQLBuilderBroker sqlBroker = SQLBuilderBroker.GetSQLBuilderBroker();
            return sqlBroker.GetQueryView(sql, pagingSize);
        }

        public DataTable SearchQuestionsByAuthor(string authorOID, string keywords, PagingSize pagingSize)
        {
            if (string.IsNullOrEmpty(pagingSize.SearchKey)) pagingSize.SearchKey = "1=1";

            string sql = "SELECT * FROM T_QUE_Question";
            string where = MakeSearchWhere(keywords);

            if (!string.IsNullOrEmpty(where))
            {
                pagingSize.SearchKey = string.Format("({0}) AND F_UserOID = '{1}' AND ({2})", pagingSize.SearchKey, authorOID, where);
            }
            else
            {
                pagingSize.SearchKey = string.Format("({0}) AND F_UserOID = '{1}'", pagingSize.SearchKey, authorOID);
            }
            pagingSize.SortExpression = " F_UPDATEDATE DESC ";

            SQLBuilderBroker sqlBroker = SQLBuilderBroker.GetSQLBuilderBroker();
            return sqlBroker.GetQueryView(sql, pagingSize);
        }

        public DataTable SearchQuestionsToExpert(string ExpertOID, string keywords, PagingSize pagingSize)
        {
            if (string.IsNullOrEmpty(pagingSize.SearchKey)) pagingSize.SearchKey = "1=1";

            string sql = "SELECT * FROM T_QUE_Question";
            string where = MakeSearchWhere(keywords);

            if (!string.IsNullOrEmpty(where))
            {
                pagingSize.SearchKey = string.Format("({0}) AND F_OID IN ( SELECT F_QuestionOID FROM T_QUE_QuestToExperts WHERE F_ExpertOID = '{1}') AND ({2})", pagingSize.SearchKey, ExpertOID, where);
            }
            else
            {
                pagingSize.SearchKey = string.Format("({0}) AND (F_OID IN ( SELECT F_QuestionOID FROM T_QUE_QuestToExperts WHERE F_ExpertOID = '{1}'))", pagingSize.SearchKey, ExpertOID);
            }
            pagingSize.SortExpression = " F_UPDATEDATE DESC ";

            SQLBuilderBroker sqlBroker = SQLBuilderBroker.GetSQLBuilderBroker();
            return sqlBroker.GetQueryView(sql, pagingSize);
        }

        public DataTable SearchQuestionsByAnswerPoster(string PosterOID, string keywords, PagingSize pagingSize)
        {
            if (string.IsNullOrEmpty(pagingSize.SearchKey)) pagingSize.SearchKey = "1=1";

            string sql = "SELECT * FROM T_QUE_Question";
            string where = MakeSearchWhere(keywords);

            if (!string.IsNullOrEmpty(where))
            {
                pagingSize.SearchKey = string.Format("({0}) AND (F_OID IN ( SELECT F_QuestionOID FROM T_QUE_Answer WHERE F_UserOID = '{1}')) AND ({2})", pagingSize.SearchKey, PosterOID, where);
            }
            else
            {
                pagingSize.SearchKey = string.Format("({0}) AND (F_OID IN ( SELECT F_QuestionOID FROM T_QUE_Answer WHERE F_UserOID = '{1}'))", pagingSize.SearchKey, PosterOID);
            }
            pagingSize.SortExpression = " F_UPDATEDATE DESC ";

            SQLBuilderBroker sqlBroker = SQLBuilderBroker.GetSQLBuilderBroker();
            return sqlBroker.GetQueryView(sql, pagingSize);
        }

        public DataTable SearchQuestionsRelatedToUser(string UserOID, string keywords, PagingSize pagingSize)
        {
            if (string.IsNullOrEmpty(pagingSize.SearchKey)) pagingSize.SearchKey = "1=1";

            string sql = "SELECT * FROM T_QUE_Question";
            string where = MakeSearchWhere(keywords);

            if (!string.IsNullOrEmpty(where))
            {
                pagingSize.SearchKey = string.Format("({0}) AND (F_OID IN (SELECT F_QUESTIONOID FROM T_QUE_ANSWER WHERE F_USEROID = '{1}') OR F_USEROID = '{1}' ) AND ({2})", pagingSize.SearchKey, UserOID, where);
            }
            else
            {
                pagingSize.SearchKey = string.Format("({0}) AND (F_OID IN (SELECT F_QUESTIONOID FROM T_QUE_ANSWER WHERE F_USEROID = '{1}') OR F_USEROID = '{1}' ) ", pagingSize.SearchKey, UserOID);
            }
            pagingSize.SortExpression = " F_UPDATEDATE DESC ";

            SQLBuilderBroker sqlBroker = SQLBuilderBroker.GetSQLBuilderBroker();
            return sqlBroker.GetQueryView(sql, pagingSize);
        }

        public void UpdateQuestionStatue(string oid, QuestionStatus status)
        {
            Hashtable htKeys = new Hashtable();
            htKeys.Add("OID", oid);
            htKeys.Add("Status", (int)status);
            SqlMap.Update("UpdateQuestionStatus", htKeys);
        }

        /// <summary>
        /// 获取所有未审核用户
        /// </summary>
        /// <returns></returns>
        public int GetUnPassedQuestionsCount()
        {
            //return 0;
            // HACK,wdong
            int value = (int)(QuestionStatus.UnPassed);
            return (int)SqlMap.QueryForObject("SelectUnPassedQuestionsCount", value);
        }

        public QuestionEntity GetQuestionEntityByOID(string OID)
        {
            if (string.IsNullOrEmpty(OID))
            {
                return null;
            }

            Hashtable hsQuery = new Hashtable();
            hsQuery.Add("OID", OID);
            return GetEntity(hsQuery) as QuestionEntity;
        }

        public IList<QuestionEntity> GetDomainLastQuestion(string DomainOID, int Count)
        {
            Hashtable htKeys = new Hashtable();
            if (Count > 0)
            {
                htKeys["PREFIX"] = string.Format(" TOP {0} * ", Count);
            }
            else
            {
                htKeys["PREFIX"] = " * ";
            }
            htKeys["DomainOID"] = DomainOID;

            return SqlMap.QueryForList<QuestionEntity>("SelectLastQuestionsByDomainOID", htKeys);
        }

        public IList<QuestionEntity> GetDomainHotQuestion(string DomainOID, int Count)
        {
            Hashtable htKeys = new Hashtable();
            if (Count > 0)
            {
                htKeys["PREFIX"] = string.Format(" TOP {0} * ", Count);
            }
            else
            {
                htKeys["PREFIX"] = " * ";
            }
            htKeys["DomainOID"] = DomainOID;

            return SqlMap.QueryForList<QuestionEntity>("SelectHotQuestionsByDomainOID", htKeys);
        }

        public DataTable GetDomainAllPassedQuestions(string DomainOID, PagingSize PagingSize)
        {
            string sql = "SELECT * FROM T_QUE_Question WHERE F_OID IN (SELECT F_QuestionOID FROM T_QUE_QuestionDomain WHERE F_DomainOID = '{0}') AND  F_Status <> 0";
            sql = string.Format(sql, DomainOID);

            return SYS.Common.Broker.SQLBuilderBroker.GetSQLBuilderBroker().GetQueryView(sql, PagingSize);
        }

        public IList<QuestionEntity> GetDomainUnsolvedQuestionsByStatus(string DomainOID, int Count)
        {
            Hashtable htKeys = new Hashtable();
            if (Count > 0)
            {
                htKeys["PREFIX"] = string.Format(" TOP {0} * ", Count);
            }
            else
            {
                htKeys["PREFIX"] = " * ";
            }
            htKeys["DomainOID"] = DomainOID;

            return SqlMap.QueryForList<QuestionEntity>("GetDomainUnsolvedQuestionsByStatus", htKeys);
        }

        public DataTable GetDomainUnsolvedQuestionsByStatus(string DomainOID, PagingSize PagingSize)
        {
            string sql = "SELECT * FROM T_QUE_Question WHERE F_OID IN (SELECT F_QuestionOID FROM T_QUE_QuestionDomain WHERE F_DomainOID = '{0}') AND  (F_Status = 1 OR F_Status = 2) AND F_FAQ=0";
            sql = string.Format(sql, DomainOID);

            return SYS.Common.Broker.SQLBuilderBroker.GetSQLBuilderBroker().GetQueryView(sql, PagingSize);
        }

        public IList<QuestionEntity> GetDomainResolvedQuestionsByStatus(string DomainOID, int Count)
        {
            Hashtable htKeys = new Hashtable();
            if (Count > 0)
            {
                htKeys["PREFIX"] = string.Format(" TOP {0} * ", Count);
            }
            else
            {
                htKeys["PREFIX"] = " * ";
            }
            htKeys["DomainOID"] = DomainOID;

            return SqlMap.QueryForList<QuestionEntity>("GetDomainResolvedQuestionsByStatus", htKeys);
        }

        public DataTable GetDomainResolvedQuestionsByStatus(string DomainOID, PagingSize PagingSize)
        {
            string sql = "SELECT * FROM T_QUE_Question WHERE F_OID IN (SELECT F_QuestionOID FROM T_QUE_QuestionDomain WHERE F_DomainOID = '{0}') AND  (F_Status = 3 OR F_FAQ=1)";
            sql = string.Format(sql, DomainOID);

            return SYS.Common.Broker.SQLBuilderBroker.GetSQLBuilderBroker().GetQueryView(sql, PagingSize);
        }

        public IList<QuestionEntity> GetLastQuestions(int Count)
        {
            return SqlMap.QueryForList<QuestionEntity>("SelectLastQuestions", Count);
        }

        public IList<QuestionEntity> GetHotQuestion(int Count)
        {
            return SqlMap.QueryForList<QuestionEntity>("SelectHotQuestions", Count);
        }

        public IList<QuestionEntity> GetDomainFAQs(string DomainOID, int Count)
        {
            Hashtable htKeys = new Hashtable();
            htKeys["PREFIX"] = Count > 0 ? string.Format("TOP {0} * ", Count) : "*";
            htKeys["DomainOID"] = DomainOID;

            return SqlMap.QueryForList<QuestionEntity>("GetDomainFAQs", htKeys);
        }

        public DataTable GetDomainFAQs(string DomainOID, PagingSize PagingSize)
        {
            if(string.IsNullOrEmpty(PagingSize.SearchKey)) PagingSize.SearchKey = "1=1";
            
            string sql = "SELECT * FROM T_QUE_Question";
            
            PagingSize.SearchKey = string.Format("({0}) AND ({1})",
                PagingSize.SearchKey,
                string.Format("F_OID IN ( SELECT F_QuestionOID FROM T_QUE_QuestionDomain WHERE F_DomainOID = '{0}') AND  F_Status <> 0 AND F_FAQ = 1", DomainOID)
            );

            return SQLBuilderBroker.GetSQLBuilderBroker().GetQueryView(sql, PagingSize);
        }

        public DataTable GetUserPublishedFAQs(string UserOID, PagingSize pagingSize)
        {
            if (string.IsNullOrEmpty(pagingSize.SearchKey)) pagingSize.SearchKey = "1=1";

            string sql = "SELECT * FROM T_QUE_Question";

            if (!string.IsNullOrEmpty(pagingSize.SearchKey))
            {
                pagingSize.SearchKey = string.Format("({0}) AND F_USEROID = '{1}' AND F_FAQ = 1", pagingSize.SearchKey, UserOID);
            }

            pagingSize.SortExpression = " F_UPDATEDATE DESC ";

            SQLBuilderBroker sqlBroker = SQLBuilderBroker.GetSQLBuilderBroker();
            return sqlBroker.GetQueryView(sql, pagingSize);
        }

        #endregion

        #region Public Static Method
        public static string TranslateStatus(QuestionStatus status)
        {
            switch (status)
            {
                case QuestionStatus.UnPassed:
                    {
                        return "未审核问题";
                    }
                case QuestionStatus.Unsolve:
                case QuestionStatus.HasAnswer:
                    {
                        return "待解决问题";
                    }
                case QuestionStatus.Accepted:
                    {
                        return "已解决问题";
                    }
                default:
                    {
                        return "状态不详";
                    }
            }
        }

        public static string TranslateQuestionStatus(QuestionStatus status)
        {
            switch (status)
            {
                case QuestionStatus.UnPassed:
                    {
                        return "未审核";
                    }
                case QuestionStatus.Unsolve:
                    {
                        return "未回答";
                    }
                case QuestionStatus.HasAnswer:
                case QuestionStatus.Accepted:
                    {
                        return "已回答";
                    }
                default:
                    {
                        return "不详";
                    }
            }
        }

        public static string TranslateAnswerStatus(QuestionStatus status)
        {
            switch (status)
            {
                case QuestionStatus.UnPassed:
                    {
                        return "未审核";
                    }
                case QuestionStatus.HasAnswer:
                case QuestionStatus.Unsolve:
                    {
                        return "未采纳";
                    }
                case QuestionStatus.Accepted:
                    {
                        return "已采纳";
                    }
                default:
                    {
                        return "不详";
                    }
            }
        }

        #endregion
    }
}